<?php

namespace app\admins\controller;

use think\facade\Db;
use think\facade\Log;


class Comment extends Base
{
    // 列表（表头型）
    public function index()
    {
        $map = [];
        $search = input('get.search');
        if (!empty($search)) {
            foreach ((array)$search as $k => $v) {
                if (strlen($v)) $map[] = [$k, 'like', "%{$v}%"];
            }
        }
        $data['search'] = (array)$search;
        $data['page'] = max(1, (int)input('get.page'));
        $data['pageSize'] = (int)input('get.limit', 10);
        // 分页查询
        $list = Db::table('comment')->where($map)->where('pid', 0)->order('id', 'desc')->paginate($data['pageSize']);
        $replys = Db::table('comment')->whereIn('pid', array_column($list->items(), 'id'))->order('id', 'desc')->select()->toArray();
        $articles = Db::table('article')->whereIn('id', array_column($list->items(), 'post_id'))->select()->toArray();
        $list = $list->each(function ($item, $key) use ($articles, $replys) {
            $article = current(array_filter($articles, function ($ele) use ($item) {
                return $ele['id'] == $item['post_id'];
            }));
            $item['replys'] = array_filter($replys, function ($reply) use ($item) {
                return $reply['pid'] == $item['id'];
            });
            $item['article'] = '<a href="/detail/' . $article['id'] . '.html" title="">' . $article['title'] . '</a>';
            return $item;
        });
        $data['total'] = $list->total();
        $data['items'] = $list->items();
        return view('/comment/index', $data);
    }

    // 回复
    public function reply()
    {
        $id = (int)$this->request->param('id');
        $row = Db::table('comment')->where('id', $id)->find();
        empty($row) && $this->err(['code' => 1, 'msg' => '数据不存在']);
        // 异步回复时
        if ($this->request->isAjax()) {
            $this->check(['__token__', 'id', 'name', 'comment']);
            $param = $this->request->post();
            empty($param['recomment']) && $this->err(['code' => 1, 'msg' => '回复评论不能为空']);
            $data['name'] = $this->auth['username'] ?: 'admin';
            $data['post_id'] = $row['post_id'];
            $data['comment'] = $param['recomment'];
            $data['pid'] = $id;
            $data['uid'] = 0 - $this->auth['id'];
            $data['status'] = 0;
            $data['add_time'] = time();
            Db::table('comment')->insert($data);
            Db::table('article')->where('id', $data['post_id'])->inc('comments')->update();
            $this->err(['code' => 0, 'msg' => '回复成功']);
            exit;
        }

        // 渲染
        $data['row'] = $row;
        return view('/comment/reply', $data);
    }

    // 编辑
    public function edit()
    {
        $id = (int)input('get.id');
        $row = Db::table('comment')->where('id', $id)->find();
        empty($row) && $this->err(['code' => 1, 'msg' => '数据不存在']);
        // 渲染
        $data['row'] = $row;
        return view('/comment/edit', $data);
    }

    // 保存编辑
    public function save_edit()
    {
        // 验证
        $this->check(['__token__', 'id', 'name', 'comment', 'status']);
        $id = (int)input('post.id');
        $row = Db::table('comment')->where('id', $id)->find();
        empty($row) && $this->err(['code' => 1, 'msg' => '数据不存在']);
        // 数据
        $data = $this->request->only(['name', 'comment', 'status']); //允许的字段
        // 操作
        try {
            Db::table('comment')->where('id', $row['id'])->update($data);
        } catch (\Exception $e) {
            $this->log($e->getMessage(), __LINE__ - 2);
            $this->err(['code' => 1, 'msg' => '保存失败']);
        }
        $this->err(['code' => 0, 'msg' => '保存成功']);
    }

    // 删除
    public function del()
    {
        $id = array_map('intval', (array)input('post.id'));
        $rows = Db::table('comment')->whereIn('id', $id)->select();
        $rows->isEmpty() && $this->err(['code' => 1, 'msg' => '数据不存在']);
        // 回复的评论
        $reply_ids = Db::table('comment')->whereIn('pid', $id)->select()->column('id');
        $id = array_unique(array_merge($id, $reply_ids));
        // 操作
        try {
            Db::table('comment')->whereIn('id', $id)->delete();
        } catch (\Exception $e) {
            $this->log($e->getMessage(), __LINE__ - 2);
            $this->err(['code' => 1, 'msg' => '删除失败']);
        }
        $this->err(['code' => 0, 'msg' => '删除成功']);
    }

    // 待审核
    public function pending()
    {
        $id = (array)input('post.id');
        $rows = Db::table('comment')->whereIn('id', $id)->select();
        $rows->isEmpty() && $this->err(['code' => 1, 'msg' => '数据不存在']);
        // 操作
        try {
            Db::table('comment')->whereIn('id', $id)->update(['status' => 1]);
        } catch (\Exception $e) {
            $this->log($e->getMessage(), __LINE__ - 2);
            $this->err(['code' => 1, 'msg' => '待审失败']);
        }
        $this->err(['code' => 0, 'msg' => '待审成功']);
    }

    // 审核通过
    public function passed()
    {
        $id = (array)input('post.id');
        $rows = Db::table('comment')->whereIn('id', $id)->select();
        $rows->isEmpty() && $this->err(['code' => 1, 'msg' => '数据不存在']);
        // 操作
        try {
            Db::table('comment')->whereIn('id', $id)->update(['status' => 0]);
        } catch (\Exception $e) {
            $this->log($e->getMessage(), __LINE__ - 2);
            $this->err(['code' => 1, 'msg' => '审核失败']);
        }
        $this->err(['code' => 0, 'msg' => '审核成功']);
    }

    // 垃圾评论
    public function spam()
    {
        $id = (array)input('post.id');
        $rows = Db::table('comment')->whereIn('id', $id)->select();
        $rows->isEmpty() && $this->err(['code' => 1, 'msg' => '数据不存在']);
        // 操作
        try {
            Db::table('comment')->whereIn('id', $id)->update(['status' => 2]);
        } catch (\Exception $e) {
            $this->log($e->getMessage(), __LINE__ - 2);
            $this->err(['code' => 1, 'msg' => '标记垃圾评论失败']);
        }
        $this->err(['code' => 0, 'msg' => '标记垃圾评论成功']);
    }

    // 属性修改
    public function modify()
    {
        // 验证
        try {
            $this->validate($this->request->post(), [
                'id|ID' => 'require|number',
                'field|字段' => 'require',
                'value|值' => 'require',
            ]);
        } catch (\Exception $e) {
            $this->err(['code' => 1, 'msg' => $e->getMessage()]);
            exit();
        }
        $id = (int)input('post.id');
        $row = Db::table('comment')->where('id', $id)->find();
        empty($row) && $this->err(['code' => 1, 'msg' => '数据不存在']);
        // 非法字段
        $field = input('post.field');
        $value = input('post.value');
        (empty($field) || !is_string($field)) && $this->err(['code' => 1, 'msg' => '字段错误']);
        is_null($value) && $this->err(['code' => 1, 'msg' => '值错误']);
        !in_array($field, ['comment', 'status']) && $this->err(['code' => 1, 'msg' => '该字段不允许修改']); //允许的字段
        // 验证属性
        $data = [$field => $value];
        $this->check([$field], $data);
        // 操作
        try {
            Db::table('comment')->where('id', $id)->update($data);
        } catch (\Exception $e) {
            $this->log($e->getMessage(), __LINE__ - 2);
            $this->err(['code' => 1, 'msg' => '修改失败']);
        }
        $this->err(['code' => 0, 'msg' => '修改成功']);
    }

    // 私有方法：验证
    private function check($field = [], $data = null)
    {
        $rule = [
            '__token__|令牌' => 'require|token',
            'id|ID' => 'require|number',
            'pid|父级评论' => 'require|number',
            'post_id|文章ID' => 'require|number',
            'name|姓名' => 'requireWith:name|chsDash',
            'comment|评论内容' => 'require|unique:comment', // 验证token且值唯一
            'add_time|时间' => 'require|number',
            'status|状态' => 'require|in:0,1',
        ];
        $validate = [];
        foreach ($rule as $key => $value) {
            [$name,] = explode('|', $key);
            if (in_array($name, $field)) {
                $validate[$key] = $value;
            }
        }
        try {
            $this->validate($data ?: $this->request->post(), $validate);
        } catch (\Exception $e) {
            $this->err(['code' => 1, 'msg' => $e->getMessage()]);
            exit;
        }
    }

    // 私有方法：错误消息
    private function err($args = ['code' => 1, 'msg' => 'Error!'])
    {
        if ($this->request->isAjax()) {
            echo json_encode($args);
        } else {
            if (!empty($args['msg']))
                echo '<p style="text-align:center;color:#393D49;font-size:20px;">' . $args['msg'] . '</p>';
            if (!empty($args['url'])) {
                echo '<script>
                    setTimeout(function () {
                        var _ta = window.location;
                        if (self.frameElement && self.frameElement.tagName == "IFRAME") {
                            _ta = parent.window.location;
                        }
                        _ta.href = "' . $args['url'] . '";
                    }, 1000);
                    </script>';
            }
        }
        if (!empty($args['code'])) exit;
    }

    // 私有方法：错误日志
    private function log($msg, $line)
    {
        Log::write('/' . $this->app->http->getName() . '/' . $this->request->controller() . '/' . $this->request->action() . ' -> Line ' . $line . ': ' . $msg, 'notice');
    }
}
